package Day021_反射_注解.demo4_反射之构造方法;

import java.lang.reflect.Constructor;

/**
 * @Author：pengzhilin
 * @Date: 2020/5/14 10:12
 */
public class Test1 {
    public static void main(String[] args) throws Exception{
        /*
            - 通过反射获取类的构造方法,并执行构造方法创建该类的对象
                - Constructor类概述
                    概述:类中的每一个构造方法都是一个Constructor类的对象
                    通过反射获取类的构造方法,其实就是获取该构造方法对于的Constructor对象

                - 通过反射获取类的构造方法: 使用Class类中的方法
                   我们每一个类都会有一个对于的Class对象,所以该类中的构造方法就在我们的Class对象中,
                   所以可以使用Class对象获取构造方法
                   Class类中与Constructor相关的方法
                        1. Constructor getConstructor(Class... parameterTypes)  获取单个public修饰的构造方法
                                * 根据参数类型获得对应的Constructor对象。
                                * 只能获得public修饰的构造方法
                         2. Constructor getDeclaredConstructor(Class... parameterTypes) 获取单个构造方法
                                * 根据参数类型获得对应的Constructor对象
                                * 可以是public、protected、(默认)、private修饰符的构造方法。
                         3. Constructor[] getConstructors() 获取所有public修饰的构造方法
                                获得类中的所有构造方法对象，只能获得public的
                         4. Constructor[] getDeclaredConstructors() 获取所有构造方法
                                获得类中的所有构造方法对象
                                可以是public、protected、(默认)、private修饰符的构造方法。
                    记忆方法:
                        1. 加了s的就是获取多个,不加s的就是获取单个
                        2. 加了Declared的就是获取任意修饰符修饰的构造方法,不加就只能获取public修饰的构造方法

                 小结:
                     Constructor getDeclaredConstructor(Class... parameterTypes) 获取单个构造方法
                     Constructor[] getDeclaredConstructors() 获取所有构造方法

                - 通过反射执行构造方法:使用Constructor对象中的方法,来执行该对象表示的构造方法
                    Constructor对象常用方法
                        1. T newInstance(Object... initargs)
                            根据指定的参数创建对象
                        2. void setAccessible(true)
                           设置"暴力反射"——是否取消权限检查，true取消权限检查，false表示不取消

         */
        // 0.获取Student类的Class对象
        Class<?> c = Class.forName("com.itheima.demo4_反射之构造方法.Student");

        // 1.获取单个public修饰的构造方法
        // Constructor getConstructor(Class... parameterTypes)  获取单个public修饰的构造方法
        //    参数:传入你要获取的构造方法的参数类型的Class对象

        // 获取Student类的空参构造方法
        Constructor<?> cons1 = c.getConstructor();
        System.out.println(cons1);

        // 获取Student类的带有三个参数的构造方法,并且参数的类型顺序为:String,String,int
        Constructor<?> cons2 = c.getConstructor(String.class,String.class, int.class);

        // public Student(String name,String sex,int.class);
        // public Student(String name,int.class,String sex);

        System.out.println(cons2);

        // 2.获取单个非public修饰的构造方法
        // Constructor getDeclaredConstructor(Class... parameterTypes) 获取单个构造方法
        //    参数:传入你要获取的构造方法的参数类型的Class对象

        // 获取Student类的带有2个参数的构造方法,并且参数的类型顺序为:String,int
        Constructor<?> cons3 = c.getDeclaredConstructor(String.class, int.class);
        System.out.println(cons3);

        System.out.println("============================================");
        // 3.获取多个public修饰的方法
        // Constructor[] getConstructors() 获取所有public修饰的构造方法
        Constructor<?>[] conArr1 = c.getConstructors();
        for (Constructor<?> con : conArr1) {
            System.out.println(con);
        }

        System.out.println("============================================");
        // 4.获取所有修饰的方法
        // Constructor[] getDeclaredConstructors() 获取所有构造方法
        Constructor<?>[] conArr2 = c.getDeclaredConstructors();
        for (Constructor<?> con : conArr2) {
            System.out.println(con);
        }

    }
}
